{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "c8d0c724",
   "metadata": {},
   "source": [
    "点云数据也可以进行卷积，我们首先对数据进行格式上的定义和整理。\n",
    "\n",
    "代码中 `input_image` 是 `[B, N, 3, 1]`：\n",
    "\n",
    "`B`：批次大小（一次处理多少个样本）\n",
    "\n",
    "`N`：点云的点数（每个样本有 N 个点，看作「高度」）\n",
    "\n",
    "`3`：每个点的坐标维度（x,y,z，看作「宽度」）\n",
    "\n",
    "`1`：输入通道数（这里每个坐标是单独的通道，只有 1 个通道）\n",
    "\n",
    "普通的点云数据是不含有通道这个维度的。\n",
    "**为什么是 4D？** ：TensorFlow 的 2D 卷积要求输入是 4D，即使我们处理的是点云（3D 坐标），也要通过 `expand_dims` 升维为 4D（最后一维是通道数）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f3c6a1d6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Microsoft Visual C++ Redistributable is not installed, this may lead to the DLL load failure.\n",
      "It can be downloaded at https://aka.ms/vs/16/release/vc_redist.x64.exe\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "import torch.nn as nn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "91cee44b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 设置参数\n",
    "B = 2      # 批次大小\n",
    "N = 100    # 点云点数（高度）\n",
    "C_in = 1   # 输入通道数\n",
    "C_out = 4  # 输出通道数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "17f363a4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "输入点云形状: torch.Size([2, 100, 3, 1])\n"
     ]
    }
   ],
   "source": [
    "# 创建模拟点云数据 [B, N, 3, 1]\n",
    "input_image = torch.randn(B, N, 3, C_in)\n",
    "print(f\"输入点云形状: {input_image.shape}\")  # 输出: [2, 100, 3, 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "4afe73df",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "点云内容为： tensor(0.1931)\n"
     ]
    }
   ],
   "source": [
    "# 取第一个Batch的内容\n",
    "input_image_zero = input_image[0]\n",
    "print(\"点云内容为：\",input_image_zero[20][1][0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "5b857e2a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "调整后形状: torch.Size([2, 1, 100, 3])\n"
     ]
    }
   ],
   "source": [
    "# 由于PyTorch的Conv2d期望输入格式为 [B, C, H, W]\n",
    "# 需要调整维度顺序：[B, N, 3, 1] → [B, 1, N, 3]\n",
    "reshaped_input = input_image.permute(0, 3, 1, 2)\n",
    "print(f\"调整后形状: {reshaped_input.shape}\")  # 输出: [2, 1, 100, 3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "e6a88cea",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义点云卷积层（保持点数不变的配置）\n",
    "point_cloud_conv = nn.Conv2d(\n",
    "    in_channels=C_in,\n",
    "    out_channels=C_out,\n",
    "    kernel_size=(3, 3),  # 高度方向核大小为3，宽度方向为3\n",
    "    stride=1,\n",
    "    padding=(1, 1)       # 保持高度和宽度不变的填充\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "43acaece",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "卷积输出形状: torch.Size([2, 4, 100, 3])\n"
     ]
    }
   ],
   "source": [
    "# 应用卷积\n",
    "output = point_cloud_conv(reshaped_input)\n",
    "print(f\"卷积输出形状: {output.shape}\")  # 输出: [2, 4, 100, 3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "31d96fcc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "转回点云格式的形状: torch.Size([2, 100, 3, 4])\n"
     ]
    }
   ],
   "source": [
    "# 将结果转回点云格式 [B, N, 3, C_out]\n",
    "output_cloud = output.permute(0, 2, 3, 1)\n",
    "print(f\"转回点云格式的形状: {output_cloud.shape}\")  # 输出: [2, 100, 3, 4]"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "my_env",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
